/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.xuexiang.xui_lib.component.edittext;

import ohos.agp.components.AttrHelper;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.multimodalinput.event.KeyEvent;

import com.xuexiang.xui_lib.ResourceTable;

/**
 * VerifyCodeEditText
 *
 * @since 2021-03-24
 */
public class VerifyCodeEditText extends DependentLayout {
    private static final int FIVE = 5;
    private static final int TWOZERO = 20;
    private static final int FOURZERO = 40;
    private DirectionalLayout mLlContainer;
    /**
     * 输入框数量
     */
    private int mEtNumber;

    /**
     * 输入框的宽度
     */
    private int mEtWidth;

    /**
     * 输入框文字颜色
     */
    private int mEtTextColor;

    /**
     * 输入框文字大小
     */
    private float mEtTextSize;

    /**
     * 输入框获取焦点时背景
     */
    private ShapeElement mBackgroundFocus;
    /**
     * 输入框没有焦点时背景
     */
    private ShapeElement mBackgroundNormal;
    /**
     * 输入框分割线
     */
    private ShapeElement mEtDivider;
    /**
     * 是否是密码模式
     */
    private boolean mIsPwd;
    /**
     * 密码模式时圆的半径
     */
    private float mPwdRadius;

    /**
     * 存储TextView的数据 数量由自定义控件的属性传入
     */
    private PwdTextView[] mPwdTextViews;
    private PwdEditText mEditText;
    private int width;
    private int height;

    private OnInputListener mOnInputListener; // 输入完成 和 删除成功 的监听

    private Context context;

    /**
     * 构造函数
     *
     * @param context
     */
   /* public VerifyCodeEditText(Context context) {
        this(context, null);
    }*/

    /**
     * 构造函数
     *
     * @param context
     * @param attrSet
     */
    public VerifyCodeEditText(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    /**
     * 构造函数
     *
     * @param context
     * @param attrSet
     * @param styleName
     */
    public VerifyCodeEditText(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        this.context = context;
        init(context, attrSet, styleName);
    }

    public void setOnInputListener(OnInputListener onInputListener) {
        mOnInputListener = onInputListener;
    }

    /**
     * setNumber
     *
     * @param attrSet
     */
    public void setNumber(AttrSet attrSet) {
        mEtNumber = attrSet.getAttr("mEtNumber").get().getIntegerValue();
        mIsPwd = attrSet.getAttr("mIsPwd").get().getBoolValue();
        mEtWidth = AttrHelper.vp2px(attrSet.getAttr("mEtWidth").get().getIntegerValue(), context);
        mEtTextSize = AttrHelper.vp2px(attrSet.getAttr("mEtTextSize").get().getIntegerValue(), context);
        mPwdRadius = AttrHelper.vp2px(attrSet.getAttr("mPwdRadius").get().getIntegerValue(), context);
    }

    /**
     * 初始化 布局和属性
     *
     * @param context1
     * @param attrSet
     * @param defStyleAttr
     */
    private void init(Context context1, AttrSet attrSet, String defStyleAttr) {
        LayoutScatter.getInstance(context1).parse(ResourceTable.Layout_xui_layout_verify_code, this, true);
        mLlContainer = (DirectionalLayout) findComponentById(ResourceTable.Id_ll_container);
        mEditText = (PwdEditText) findComponentById(ResourceTable.Id_et_input);
        setNumber(attrSet);
        mEtTextColor = Color.getIntColor("#000000");

        // 当xml中未配置时 这里进行初始配置默认图片
        boolean vcetFlag = false;
        if (attrSet.getAttr("vcet_flag").get().getBoolValue()) {
            mBackgroundFocus = (ShapeElement) attrSet.getAttr("vcet_bg_focus").get().getElement();
            mBackgroundNormal = (ShapeElement) attrSet.getAttr("vcet_bg_normal").get().getElement();
            vcetFlag = true;
        }
        if (mEtDivider == null) {
            mEtDivider = new ShapeElement(context, ResourceTable.Graphic_vcet_shape_divider);
        }
        if (mBackgroundFocus == null) {

            mBackgroundFocus = new ShapeElement(context, ResourceTable.Graphic_vcet_shape_bg_focus);
        }
        if (mBackgroundNormal == null) {
            mBackgroundNormal = new ShapeElement(context, ResourceTable.Graphic_vcet_shape_bg_normal);
        }
        setEstimateSizeListener(new EstimateSizeListener() {
            @Override
            public boolean onEstimateSize(int i, int i1) {
                width = EstimateSpec.getSize(i);
                height = EstimateSpec.getSize(i1);
                return false;
            }
        });
        addDrawTask(new DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                setComponentMinSize(width, height);
            }
        });
        initUi(vcetFlag);
    }

    // 初始UI
    private void initUi(boolean vcetFlag) {
        initTextViews(context, mEtNumber, mEtWidth, mEtDivider, mEtTextSize, mEtTextColor, vcetFlag);
        initEtContainer(mPwdTextViews);
        setListener();
    }

    /**
     * 初始化TextView
     *
     * @param context1
     * @param etNumber
     * @param etWidth
     * @param etDividerDrawable
     * @param etTextSize
     * @param etTextColor
     * @param vceFlag
     */
    public void initTextViews(Context context1, int etNumber, int etWidth, ShapeElement etDividerDrawable,
                              float etTextSize, int etTextColor, boolean vceFlag) {
        mEditText.setTextCursorVisible(false);
        mEditText.setTextSize(etNumber);
        if (etDividerDrawable != null) {
            etDividerDrawable.setBounds(0, 0, etDividerDrawable.getMinWidth(), etDividerDrawable.getMinHeight());
        }
        mPwdTextViews = new PwdTextView[mEtNumber];
        for (int i1 = 0; i1 < mEtNumber; i1++) {
            PwdTextView textView = new PwdTextView(context1);
            textView.setTextSize((int) mEtTextSize);
            textView.setTextColor(Color.BLACK);
            textView.setWidth(mEtWidth);
            textView.setHeight(mEtWidth);
            textView.setMarginLeft(AttrHelper.vp2px(FIVE, getContext()));
            textView.setMarginRight(AttrHelper.vp2px(FIVE, getContext()));
            if (i1 == 0) {
                textView.setBackground(mBackgroundFocus);
            } else {
                textView.setBackground(mBackgroundNormal);
            }
            if (vceFlag) {
                textView.setHeight(mEtWidth + AttrHelper.vp2px(TWOZERO, context));
                textView.setTextAlignment(TextAlignment.HORIZONTAL_CENTER | TextAlignment.TOP);
                textView.setPaddingBottom(AttrHelper.vp2px(FOURZERO, context1));
            } else {
                textView.setTextAlignment(TextAlignment.CENTER);
            }
            textView.setFocusable(FOCUS_DISABLE);
            mPwdTextViews[i1] = textView;
        }
    }

    /**
     * 初始化存储TextView 的容器
     *
     * @param mTextViews
     */
    private void initEtContainer(PwdTextView[] mTextViews) {
        for (PwdTextView mTextView : mTextViews) {
            mLlContainer.addComponent(mTextView);
        }
        setEstimateSizeListener(new EstimateSizeListener() {
            @Override
            public boolean onEstimateSize(int i, int i1) {
                EstimateSpec.getSize(i);
                return false;
            }
        });
    }

    private void setListener() {
        mEditText.addTextObserver(new InputNumberTextWatcher());
        mEditText.setKeyEventListener(new KeyEventListener() {
            @Override
            public boolean onKeyEvent(Component component, KeyEvent keyEvent) {
                if (keyEvent.getKeyCode() == KeyEvent.KEY_DEL && keyEvent.isKeyDown()) {
                    onKeyDelete();
                    return true;
                }
                return false;
            }
        });
    }

    private void onKeyDelete() {
        for (int i1 = mPwdTextViews.length - 1; i1 >= 0; i1--) {
            PwdTextView tv = mPwdTextViews[i1];
            if (!"".equals(tv.getText().toString().trim())) {
                if (mIsPwd) {
                    tv.clearPassword();
                }
                tv.setText("");
                tv.setBackground(mBackgroundFocus);
                if (i1 < mEtNumber - 1) {
                    mPwdTextViews[i1 + 1].setBackground(mBackgroundNormal);
                    if (i1 == 0) {
                        if (mOnInputListener != null) {
                            mOnInputListener.onClear();
                        }
                    } else {
                        if (mOnInputListener != null) {
                            mOnInputListener.onChange(getInputValue());
                        }
                    }
                } else if (i1 == mEtNumber - 1) {
                    if (mOnInputListener != null) {
                        mOnInputListener.onChange(getInputValue());
                    }
                }
                break;
            }
        }
    }

    /**
     * 监听输入框输入的数量
     *
     * @since 2021-03-11
     */
    private class InputNumberTextWatcher implements Text.TextObserver {
        @Override
        public void onTextUpdated(String s, int i, int i1, int i2) {
            String inputStr = s; // s:指示当前文本i:指示要添加的文本的开始位置i1:指示旧文本的长度i2:指示要添加的文本的长度。
            if (inputStr != null && inputStr.length() != 0) {
                String[] strArray = inputStr.split("");
                for (int j1 = 0; j1 < strArray.length; j1++) {
                    // 不能大于输入框个数
                    if (j1 > mEtNumber) {
                        break;
                    }
                    setText(strArray[i]);
                    mEditText.setText("");
                }
            }
        }
    }

    /**
     * 输入框监听
     *
     * @since 2021-04-29
     */
    public interface OnInputListener {
        /**
         * 输入完成
         *
         * @param input
         */
        void onComplete(String input);

        /**
         * 输入变化
         *
         * @param input
         */
        void onChange(String input);

        /**
         * 输入清空
         */
        void onClear();
    }

    /**
     * 获取输入文本
     *
     * @return string
     */
    public String getInputValue() {
        StringBuilder sb = new StringBuilder();
        for (Text tv : mPwdTextViews) {
            sb.append(tv.getText().toString().trim());
        }
        return sb.toString();
    }

    // 给TextView 设置文字
    private void setText(String inputContent) {
        if (inputContent == null || inputContent.length() == 0) {
            return;
        }
        for (int i1 = 0; i1 < mPwdTextViews.length; i1++) {
            PwdTextView tv = mPwdTextViews[i1];
            if ("".equals(tv.getText().toString().trim())) {
                if (mIsPwd) {
                    tv.drawPassword(mPwdRadius);
                }
                tv.setText(inputContent);
                tv.setBackground(mBackgroundNormal);
                if (i1 < mEtNumber - 1) {
                    mPwdTextViews[i1 + 1].setBackground(mBackgroundFocus);
                    if (mOnInputListener != null) {
                        mOnInputListener.onChange(getInputValue());
                    }
                } else if (i1 == mEtNumber - 1) {
                    if (mOnInputListener != null) {
                        mOnInputListener.onComplete(getInputValue());
                    }
                }
                break;
            }
        }
    }

    /**
     * 删除输入内容
     */
    public void clearInputValue() {
        for (int i1 = 0; i1 < mPwdTextViews.length; i1++) {
            if (i1 == 0) {
                mPwdTextViews[i1].setBackground(mBackgroundFocus);
            } else {
                mPwdTextViews[i1].setBackground(mBackgroundNormal);
            }
            if (mIsPwd) {
                mPwdTextViews[i1].clearPassword();
            }
            mPwdTextViews[i1].setText("");
        }
        if (mOnInputListener != null) {
            mOnInputListener.onClear();
        }
    }
}
